/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
**
****************************************************************************/

#include <qdatetime.h>
#include <qmainwindow.h>
#include <qstatusbar.h>
#include <qmessagebox.h>
#include <qmenubar.h>
#include <qapplication.h>
#include <qpainter.h>
#include <qprinter.h>
#include <qlabel.h>
#include <qimage.h>
#include <q3progressdialog.h>
#include <Q3PointArray>
#include <Q3PtrList>
#include <QPixmap>
#include <Q3PopupMenu>
#include <QMouseEvent>
#include <Q3MemArray>
#include <QDesktopWidget>
#include "canvas.h"
#include <QStyleOptionGraphicsItem>
#include <qdebug.h>
#include <stdlib.h>
#include "descargar.h"

// We use a global variable to save memory - all the brushes and pens in
// the mesh are shared.


class ImageItem: public QGraphicsRectItem
{
public:
    ImageItem( QImage img );

protected:
    void paint( QPainter *, const QStyleOptionGraphicsItem *option, QWidget *widget );
private:
    QImage image;
    QPixmap pixmap;
};


ImageItem::ImageItem( QImage img )
    : image(img)
{
    setRect(0, 0, image.width(), image.height());
    //setFlag(ItemIsMovable);
#if !defined(Q_WS_QWS)
    pixmap.convertFromImage(image, Qt::OrderedAlphaDither);
#endif
}

void ImageItem::paint( QPainter *p, const QStyleOptionGraphicsItem *option, QWidget * )
{
// On Qt/Embedded, we can paint a QImage as fast as a QPixmap,
// but on other platforms, we need to use a QPixmap.
#if defined(Q_WS_QWS)
    p->drawImage( option->exposedRect, image, option->exposedRect, Qt::OrderedAlphaDither );
#else
    p->drawPixmap( option->exposedRect, pixmap, option->exposedRect );
#endif
}


FigureEditor::FigureEditor(
	QGraphicsScene& c, QWidget* parent,
	const char* name, Qt::WindowFlags f) :
    QGraphicsView(&c,parent)
{
    setObjectName(name);
    setWindowFlags(f);
    setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
}

void FigureEditor::clear()
{
    scene()->clear();
}


static uint mainCount = 0;
static QImage *dataimg;
static QImage *ackimg;
static QImage *rttimg;
static QImage *rttcalimg;
static QImage *rttwireimg;

Main::Main(QGraphicsScene& c, QWidget* parent, const char* name, Qt::WindowFlags f) :
    QMainWindow(parent,name,f),
    canvas(c)
{
    editor = new FigureEditor(canvas);

    QMenuBar* menu = menuBar();

    Q3PopupMenu* file = new Q3PopupMenu( menu );
    file->insertItem("&Iniciar descarga", this, SLOT(descarga()), Qt::CTRL+Qt::Key_D);
    file->insertItem("&Analizador de Flujos", this, SLOT(tcp_flow_analyzer()), Qt::CTRL+Qt::Key_F);
    file->insertItem("&Limpiar pantalla", this, SLOT(clear()), Qt::CTRL+Qt::Key_L);
    file->insertItem("&Salir", qApp, SLOT(quit()), Qt::CTRL+Qt::Key_Q);
    menu->insertItem("&Inicio", file);


    Q3PopupMenu* view = new Q3PopupMenu( menu );
    view->insertItem("Ver grafica &ACKs", this, SLOT(addack()), Qt::ALT+Qt::Key_A);
    view->insertItem("Ver grafica &DATA", this, SLOT(adddata()), Qt::ALT+Qt::Key_D);
    view->insertItem("Ver grafica de &RTTs", this, SLOT(addrtt()), Qt::ALT+Qt::Key_R);
    view->insertItem("Ver grafica de &RTTs Exactos", this, SLOT(addrttcal()), Qt::ALT+Qt::Key_C);
    view->insertItem("Ver grafica de &RTTs Exactos + Aproximados", this, SLOT(addrttwire()), Qt::ALT+Qt::Key_E);
    menu->insertItem("&Graficas", view);

    menu->insertSeparator();


    menu->insertItem("&Ayuda", this, SLOT(help()), Qt::Key_F1);
    Q3PopupMenu* acerca = new Q3PopupMenu( menu );
    acerca->insertItem("Plataforma RADS 3.0",   this, SLOT(about()), Qt::Key_F2);
    acerca->insertItem("Analizador de Flujo TCP",   this, SLOT(aboutTCP()), Qt::Key_F3);
    menu->insertItem("&Acerca de",acerca);
    statusBar();

    //setCentralWidget(editor);

    tcp_flow_analyzer();

    printer = 0;

    init();
}

void Main::init()
{
    clear();

    static int r=24;
    qsrand(++r);

    mainCount++;
    dataimg = 0;
    ackimg = 0;
    rttimg = 0;
    rttcalimg = 0;
    rttwireimg = 0;

}

Main::~Main()
{
    delete printer;
    if ( !--mainCount ) {
        delete[] dataimg;
        dataimg = 0;
        delete[] ackimg;
        ackimg = 0;
        delete[] rttimg;
        rttimg = 0;
        delete[] rttcalimg;
        rttimg = 0;
        delete[] rttwireimg;
        rttimg = 0;
    }
}

void Main::descarga()
{
    QSize desktop = QApplication::desktop()->size();

    int x = (desktop.width() - d.width() ) /2;
    int y = (desktop.height() - d.height() )/2;

    d.move(x,y);

    d.show();
}

void Main::tcp_flow_analyzer()
{
    tcpflow = new MainWindow();
    setCentralWidget(tcpflow);
}

void Main::clear()
{
    editor->clear();
}

void Main::help()
{
    static QMessageBox* about = new QMessageBox( "Ayuda",
            "<h3>Atajos</h3>"
	    "<ul>"

                "<li> CTRL-D Iniciar Descarga </li>"
                "<li> CTRL-F Analizador de Flujo </li>"
                "<li> CTRL-L Limpiar Pantalla </li>"
                "<li> CTRL-D Iniciar Descarga </li>"
                "<li> CTRL-Q Salir </li>"
                "<li> Presione ALT-A Ver grafica ACKs</li>"
                "<li> Presione ALT-D Ver grafica DATA</li>"
                "<li> Presione ALT-R Ver grafica de RTTs</li>"
                "<li> Presione ALT-C Ver grafica de RTTs Exactos</li>"
                "<li> Presione ALT-E Ver grafica de &RTTs Exactos + Aproximados</li>"
                "<li> F1 Ayuda </li>"
                "<li> F2 Acerca de Plataforma de Estadisticas RADS 3.0 </li>"
               "<li> F3 Acerca de Analizador de Flujo </li>"
	    "</ul>"
            , QMessageBox::Information, 1, 0, 0, this, 0, FALSE );
    about->setButtonText( 1, "Aceptar" );
    about->show();
}

void Main::about()
{
    static QMessageBox* about = new QMessageBox( "Acerca De",
           "<h3>Plataforma de Estadisticas RADS 3.0</h3>"

            "<p>Esta plataforma captura la traza en la transmision de un archivo, en una topologia cliente­servidor, y extrae la informacion necesaria que le permite calcular la perdida de paquetes ACKs y de DATA, tambien realiza el calculo de los RTTs y de sus estimados.<p><br>"

            "<br>Version 3:<br>"
            "<br>Codigo por:<br>"
            "<b>Edgar Castillo</b><br>"
            "<b>Joel Depablos</b><br>"
            "<b>Manuel Quintero</b><br>"
            "<br>"
            "<br>Version 2:<br>"
            "<br>Codigo por:<br>"
            "<b>Diego Uzcategui</b><br>"
            "<b>Rocky Rincon</b><br>"
            "<br>", QMessageBox::Information, 1, 0, 0, this, 0, FALSE );
    about->setButtonText( 1, "Aceptar" );
    about->show();
}
void Main::aboutTCP()
{
    static QMessageBox* about = new QMessageBox( "Acerca De",
                                                 "<h3>Analizador de Flujos TCP</h3>"
                                                 "<h4>TCP Flow Analyzer</h4>"
                                                 "<p>Sistema se encarga de realizar reconocimiento de flujos TCP entrantes y salientes de un Host y de analisis de conexion.<p><br>"
                                                 "Codigo por:<br>"
                                                 "<b>Hernan Garcia</b><br>"
            "<br>", QMessageBox::Information, 1, 0, 0, this, 0, FALSE );
    about->setButtonText( 1, "Aceptar" );
    about->show();
}


QString data_fn;
QString ack_fn;
QString rtt_fn;
QString rttcal_fn;
QString rttwire_fn;


void Main::adddata()
{
    editor = new FigureEditor(canvas/*,this*/);
    setCentralWidget(editor);

    clear();

    if ( data_fn.isEmpty() )
	return;

    if ( !dataimg ) {
        dataimg = new QImage[1];

    }

    if(not dataimg[0].load( data_fn )){
        QMessageBox::warning(this,
                             tr("Advertencia"),
                             tr("No se puede carga la imagen %1").arg(data_fn),
                             QMessageBox::Ok);
        return;
    }

    dataimg[0]=dataimg[0].smoothScale(int(dataimg[0].width()*1.6),int(dataimg[0].height()*1.3));

    QAbstractGraphicsShapeItem* i = new ImageItem(dataimg[0]);
    canvas.addItem(i);
    i->setPos(int((canvas.width()-dataimg->width())/2),int((canvas.height()-dataimg->height())/2));
    addTextdata();
}

void Main::addack()
{
    editor = new FigureEditor(canvas/*,this*/);
    setCentralWidget(editor);

    clear();
    if ( ack_fn.isEmpty() )
	return;
    if ( !ackimg ) {
        ackimg = new QImage[1];
    }

    if(not ackimg[0].load( ack_fn )){
        QMessageBox::warning(this,
                             tr("Advertencia"),
                             tr("No se puede carga la imagen %1").arg(ack_fn),
                             QMessageBox::Ok);
        return;
    }
    ackimg[0] = ackimg[0].smoothScale( int(ackimg[0].width()*1.6),int(ackimg[0].height()*1.3) );
    QAbstractGraphicsShapeItem* i = new ImageItem(ackimg[0]);
    canvas.addItem(i);
    i->setPos(0,0);
    i->setPos(int((canvas.width()-ackimg->width())/2),int((canvas.height()-ackimg->height())/2));
    addTextacks();
}

void Main::addrtt()
{
    editor = new FigureEditor(canvas/*,this*/);
    setCentralWidget(editor);

    clear();

    if ( rtt_fn.isEmpty() )
        return;
    if ( !rttimg ) {
        rttimg = new QImage[1];

    }

     if(not rttimg[0].load( rtt_fn )){
        QMessageBox::warning(this,
                             tr("Advertencia"),
                             tr("No se puede carga la imagen %1").arg(rtt_fn),
                             QMessageBox::Ok);
        return;
    }
    rttimg[0] = rttimg[0].smoothScale( int(rttimg[0].width()*1.6),int(rttimg[0].height()*1.3) );

    QAbstractGraphicsShapeItem* i = new ImageItem(rttimg[0]);
    canvas.addItem(i);
    i->setPos(0,0);
    i->setPos(int((canvas.width()-rttimg->width())/2),int((canvas.height()-rttimg->height())/2));
    addTextrtt();
}


void Main::addrttcal()
{
    editor = new FigureEditor(canvas/*,this*/);
    setCentralWidget(editor);

    clear();

    if ( rttcal_fn.isEmpty() )
        return;
    if ( !rttcalimg ) {
        rttcalimg = new QImage[1];

    }

    if(not  rttcalimg[0].load( rttcal_fn )){
        QMessageBox::warning(this,
                             tr("Advertencia"),
                             tr("No se puede carga la imagen %1").arg(rttcal_fn),
                             QMessageBox::Ok);
        return;
    }
    rttcalimg[0] = rttcalimg[0].smoothScale( int(rttcalimg[0].width()*1.6),int(rttcalimg[0].height()*1.3) );

    QAbstractGraphicsShapeItem* i = new ImageItem(rttcalimg[0]);
    canvas.addItem(i);
    i->setPos(0,0);
    i->setPos(int((canvas.width()-rttimg->width())/2),int((canvas.height()-rttimg->height())/2));
}


void Main::addrttwire()
{
    editor = new FigureEditor(canvas/*,this*/);
    setCentralWidget(editor);

    clear();

    if ( rttwire_fn.isEmpty() )
        return;
    if ( !rttwireimg ) {
        rttwireimg = new QImage[1];
    }

    if(not  rttwireimg[0].load( rttwire_fn )){
        QMessageBox::warning(this,
                             tr("Advertencia"),
                             tr("No se puede carga la imagen %1").arg(rttwire_fn),
                             QMessageBox::Ok);
        return;
    }
    rttwireimg[0] = rttwireimg[0].smoothScale( int(rttwireimg[0].width()*1.6),int(rttwireimg[0].height()*1.3) );

    QAbstractGraphicsShapeItem* i = new ImageItem(rttwireimg[0]);
    canvas.addItem(i);
    i->setPos(0,0);
    i->setPos(int((canvas.width()-rttwireimg->width())/2),int((canvas.height()-rttwireimg->height())/2));
}

ifstream in;
string cad,linea;

void Main::addTextacks()
{
    in.open("datos/resultadosACKs.txt");
    cad="";
    while(getline(in,linea)){
        cad=cad+linea+"\n";
    }
    QString r (cad.c_str());
    QGraphicsTextItem* i = canvas.addText(r);
    //i->setFlag(QGraphicsItem::ItemIsMovable);
    i->setPos(10,0);
    /*i->setPos(qrand()%int(canvas.width()),qrand()%int(canvas.height()));
    i->setZValue(qrand()%256);*/
    in.close();
}
void Main::addTextdata()
{
    in.open("datos/resultadosDATApkts.txt");
    cad="";
    while(getline(in,linea)){
        cad=cad+linea+"\n";
    }
    QString r (cad.c_str());
    QGraphicsTextItem* i = canvas.addText(r);
    //i->setFlag(QGraphicsItem::ItemIsMovable);
    i->setPos(10,0);
    //i->setPos(qrand()%int(canvas.width()),qrand()%int(canvas.height()));
    //i->setZValue(qrand()%256);
    in.close();
}
void Main::addTextrtt()
{
    in.open("datos/resultadosRTTs.txt");
    cad="";
    while(getline(in,linea)){
        cad=cad+linea+"\n";
    }
    QString r (cad.c_str());
    QGraphicsTextItem* i = canvas.addText(r);

    //i->setFlag(QGraphicsItem::ItemIsMovable);
    i->setPos(10,0);
    /*i->setPos(qrand()%int(canvas.width()),qrand()%int(canvas.height()));
    i->setZValue(qrand()%256);*/
    in.close();
}

